---------------------------------------
-- 链表   首尾相连
---------------------------------------
require("functions")
local List = class("List")

function List:ctor()
    self._fristNode = nil   -- 首节点
    self._endNode   = nil   -- 尾节点
    self._nodeCount = 0     -- 节点数
end


-- 创建一个新的节点
function List:newNode(nodeData)
    local newNode = {
        data = nodeData,
        nextNode = nil,     -- 下一节点
        prevNode = nil,     -- 上一节点
    }
    if not self._fristNode or not self._endNode then
        self._fristNode = newNode
        self._endNode = newNode
        self._fristNode.next = self._endNode
        self._endNode.prevNode = self._fristNode
    end
    return newNode
end

-- 在列表头压入一个节点
function List:push_front(nodeData)
    local node = self:newNode(nodeData)
    -- 处理原首节点
    self._fristNode.prevNode = node

    -- 替换首节点
    node.nextNode = self._fristNode
    node.prevNode = self._endNode
    self._fristNode = node

    self._nodeCount = self._nodeCount + 1
end

-- 在列表尾压入一个节点
function List:push_back(nodeData)
    local node = self:newNode(nodeData)
    -- 处理原尾节点
    self._endNode.nextNode = node

    -- 替换尾节点
    node.nextNode = self._fristNode
    node.prevNode = self._endNode
    self._endNode = node

    self._nodeCount = self._nodeCount + 1
end

-- 弹出列表头
function List:pop_front()
    if not self._fristNode then
        return nil
    end

    -- 若是最后一个节点
    if self._fristNode == self._endNode then
        local lastNode = self._fristNode
        self._fristNode = nil
        self._endNode = nil
        self._nodeCount = 0
        return lastNode
    end

    local popNode = self._fristNode
    -- 列表头替换为下一个节点
    self._fristNode = self._fristNode.nextNode
    self._fristNode.prevNode = self._endNode

    self._endNode.nextNode = self._fristNode
    self._nodeCount = self._nodeCount - 1
    return popNode
end

-- 弹出链表头并获取数据
function List:pop_front_data()
    if not self._fristNode then
        return nil
    end
    return self:pop_front().data
end

-- 弹出列表尾
function List:pop_back()
    if not self._endNode then
        return nil
    end

    -- 若是最后一个节点
    if self._fristNode == self._endNode then
        local lastNode = self._endNode
        self._fristNode = nil
        self._endNode = nil
        self._nodeCount = 0
        return lastNode
    end

    local popNode = self._endNode
    -- 列表尾替换为上一个节点
    self._endNode = self._endNode.prevNode
    self._endNode.nextNode = self._fristNode

    -- 重新指向列表头
    self._fristNode.prevNode = self._endNode
    self._nodeCount = self._nodeCount - 1
    return popNode
    -- return self:remove_node(self._endNode)
end

-- 弹出链表尾并获取数据
function List:pop_back_data()
    if not self._endNode then
        return nil
    end
    return self:pop_back().data
end


-- 移除掉链表中的某一个节点
-- e : List:remove_node(List:find(FindFunc))
function List:remove_node(findNode)
    if not findNode or self._nodeCount <= 0 then
        return
    end

    if findNode == self._fristNode then
        return self:pop_front()
    end

    if findNode == self._endNode then
        return self:pop_back()
    end

    findNode.prevNode.nextNode = findNode.nextNode
    findNode.nextNode.prevNode = findNode.prevNode

    self._nodeCount = self._nodeCount - 1
    return findNode

end

-- 获得列表头
function List:get_front()
    return self._fristNode
end

-- 获得列表头数据
function List:get_front_data()
    if not self._fristNode then return nil end
    return self._fristNode.data
end

-- 获得列表尾
function List:get_back()
    return self._endNode
end

-- 获得列表尾数据
function List:get_back_data()
    if not self._endNode then return nil end
    return self._endNode.data
end

-- 获得到指定的节点
-- 例 List:find(function(node) return node.itemId end, itemInfo.itemId)
function List:find(getNodeKeyFunc, key)
    if self._nodeCount <= 0 then
        return nil
    end
    local curNode = self._fristNode
    for i = 1, self._nodeCount do
        if getNodeKeyFunc(curNode) == key then
            return curNode
        end
        -- 指向下一个节点
        curNode = curNode.nextNode
    end
    return nil
end

-- 获取节点数量
function List:getNodeCount()
    return self._nodeCount
end

-- 清空所有节点
function List:clear()
    self:ctor()
end
-- 打印所有节点 调试用
function List:_debug_printAllNode(printNodeFunc)
    if self._nodeCount <= 0 then
        return nil
    end
    local curNode = self._fristNode
    for i = 1, self._nodeCount do
        printNodeFunc(curNode)
        -- 指向下一个节点
        curNode = curNode.nextNode
    end
    return nil
end

return List